package com.lagou.edu.factory;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.lang.model.element.VariableElement;
import java.beans.Introspector;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BeanFactory {

    private BeanFactory(){}

    /**
     * ⼯⼚类的两个任务
     * 任务⼀：加载解析xml，读取xml中的bean信息，通过反射技术实例化bean对象，然后放⼊
     map待⽤
     * 任务⼆：提供接⼝⽅法根据id从map中获取bean（静态⽅法）
     */

    private static Map<String,Object> map=new HashMap<>();

    static{
        InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.xml");
        SAXReader saxReader = new SAXReader();

        try {
            Document document = saxReader.read(is);
            Element rootElement = document.getRootElement();
            List<Element> list = rootElement.selectNodes("//bean");

            //实例化对象
            for (Element element : list) {
                String id = element.attributeValue("id");
                String className = element.attributeValue("class");
                Class<?> clazz = Class.forName(className);
                Object value = clazz.newInstance();
                map.put(id,value);
            }

            //维护bean之间的依赖关系
            List<Element> propertys = rootElement.selectNodes("//property");
            for (Element property : propertys) {
                String name = property.attributeValue("name");
                String ref = property.attributeValue("ref");
                String origin = property.getParent().attributeValue("id");
                Object obj = map.get(origin);
                Field field = obj.getClass().getDeclaredField(name);
                field.setAccessible(true);
                field.set(obj,map.get(ref));
            }
        } catch (DocumentException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    public static Object getBean(String beanMame){
        return map.get(beanMame);
    }

}
